;
nbplkup equ 8
nbpcfrm equ 9
;
nbppm.entity equ 4
nbppm.timeout equ 6
nbppm.retrycnt equ 7
nbppm.timleft equ 8
nbppm.tryleft equ 9
nbppm.rsbadr equ 10
nbppm.rsbsiz equ 12
nbppm.maxrsp equ 14
nbppm.rspnse equ 15
nbppm.dnet equ 10
nbppm.dnode equ 12
nbppm.dsckt equ 13
nbppm.sktret equ 14
;
whichnbp ldy #0
 lda (cmndlist),y ; what type of command
 and #1 ; if nbplkup, set z flag
nbp.rts rts
;
lookupname equ * ; nbp name lookup
 ldy #nbppm.rspnse ; no reply received yet
 bne nbpsetup ; bra, call nbp set up and return
;
confirmname equ * ; nbp name confirm
 ldy #nbppm.sktret ; no socket received
; jmp nbpsetup ; call nbp set up and return
;
; common routine between lookupname and confirmname
;
tempadr equ cmndlist+2
;
nbpsetup lda #0
 sta (cmndlist),y
 php
 sei
 lda nbpptrsave+1 ; are we still doing another nbp operation ?
 beq nbpstp.1 ; no, then we can do it
 jmp toomanyproc
nbpstp.1 inc outnbpid
 ldy #nbppm.entity
nbpstp.1a lda (cmndlist),y
 sta tempadr-nbppm.entity,y
 sta entityadr-nbppm.entity,y
 iny
 cpy #nbppm.entity+2
 bne nbpstp.1a
 ldx #3
 lda #0 ; calculate lenght of entity name
nbpstp.2 sec
 tay
 adc (tempadr),y
 dex
 bne nbpstp.2
 sta entitylen
 ldy #nbppm.retrycnt
 lda (cmndlist),y ; retry count
 ldy #nbppm.tryleft
 sta (cmndlist),y
 lda cmndlist
 sta nbpptrsave
 lda cmndlist+1
 sta nbpptrsave+1
 jsr nbpquery ; make a query to the network
 jmp waitdone ; wait until it is completed
;
; nbp timeout, maybe time to resend packet
; zp used are $40-41 plus those used by dowrtddp
;
nbptimeout equ *
 lda nbpptrsave+1
 beq nbp.rts ; pointer nil, just return
 sta cmndlist+1
 lda nbpptrsave
 sta cmndlist
 ldy #nbppm.timleft
 do savespace
 jsr decindy ; decrement time left
 bne nbp.rts ; still some left
 ldy #nbppm.tryleft ; else decrement retry if not zero
 lda (cmndlist),y
 beq nbptim.6 ; no more retry left
 jsr decindy
 else
 lda (cmndlist),y ; decrement time left
 sec
 sbc #1
 sta (cmndlist),y
 bne nbp.rts ; still some left
 ldy #nbppm.tryleft
 lda (cmndlist),y
 bne *+5
 jmp nbptim.6 
 sec
 sbc #1
 sta (cmndlist),y
 fin
nbpquery ldy #nbppm.timeout
 lda (cmndlist),y
 ldy #nbppm.timleft
 sta (cmndlist),y
 lda #$21 ; assume it is lkup
 sta outnbp
 jsr whichnbp
 bne nbptim.3 ; confirm
 sta ddphead+ld.dnet ; it is just local, zero dest net
 sta ddphead+ld.dnet+1
 ldx a.bridge ; do we have a bridge ?
 bne nbptim.2a ; yes
 dex ; else broadcast
 bne nbptim.2b ; bra
nbptim.2a lda #$11 ; go to bridge, command is brrq
 sta outnbp
nbptim.2b stx lapdest ; destination is bridge or broadcast
 bne nbptim.4 ; either x not 0 or acc=$11, therefore bra
nbptim.3 ldy #nbppm.dnet
nbptim.3a lda (cmndlist),y
 sta ddphead+ld.dnet-nbppm.dnet,y ; copy dest net
 iny
 cpy #nbppm.dnet+2
 bne nbptim.3a
 lda (cmndlist),y
 sta lapdest ; destination node
 do savespace
nbptim.4 ldy #move4-movetable
 jsr movedata
 else
nbptim.4 lda #2
 sta ddphead+ld.protocol ; nbp is type 2
 sta ddphead+sd.ssckt ; from socket 2
 sta ddphead+sd.dsckt ; to socket 2
 sta nbpbuffer+3 ; entity socket ; may not be needed
 lda thisnet
 sta nbpbuffer
 lda thisnet+1
 sta nbpbuffer+1
 lda ournode
 sta nbpbuffer+2
 lda #0
 sta nbpbuffer+4
 sta chksmf ; do not do checksum
 fin
 ifne opers-pascal
 ldx #>nbpwds
 ldy #<nbpwds
 else
 ldx adrnbpwds
 ldy adrnbpwds+1
 fin
 jsr dowrtddp ; do write ddp
 beq nbprts ; ok, done
 tax ; save error
 ldy #nbppm.tryleft
 lda (cmndlist),y ; any more tryies
 bne nbprts ; yes, then not a error
 txa ; get back error
 bne nbptim.8 ; bra
nbptim.6 jsr whichnbp
 beq nbptim.8 ; retry expires, terminate it with error 0
nbptim.7 lda #notconfirmed ; if to confirm, then it was not confirmed
nbptim.8 jmp nbperror
;
; socket listener for nbp
;
tblptr equ cmndlist+2
nbpbflimit equ cmndlist+4
rdmvvar equ cmndlist+6
nbprcvct equ cmndlist+7
 ifeq opers-prodos
tuplect equ $fa ; in prodos interrupt, this is saved so we can use it
 fin
;
nbplisten lda #2 ; nbp has protocol 2
 cmp ddphead+ld.protocol
 bne nbpls.01 ; if not, discard it
 jsr readnbpfx ; since acc = 2, read 2 byte for nbp
 bne nbpls.01 ; not available, do not proceed
 lda nbpbuffer
 tax
 and #$0f
 beq nbpls.01 ; no tuple, discard it
 sta tuplect
 txa
 and #$f0
 cmp #$30 ; lkup-reply ?
 beq nbpls.00 ; yes, got a reply
 cmp #$20 ; lkup ?
 bne nbpls.01 ; no, discard it
 lda nbphook+1 ; do we have a lookup hook?
 beq nbpls.01 ; no, discard it
 lda nbpbuffer+1
 ldx tuplect
nbphook equ *+1
 jmp $0000 ; nbp hook
;
nbpls.00 lda nbpptrsave+1 ; are we processing any nbp
 beq nbpls.01 ; no, ignore it
 sta cmndlist+1
 lda outnbpid
 cmp nbpbuffer+1 ; is this the one we asked
 beq nbpls.02 ; yes, process it
nbpls.01 sec  ; discard and then return
nbprts rts
nbpls.02 lda nbpptrsave
 sta cmndlist
nbpls.03 dec tuplect
 bmi nbpls.01 ; all taken care of
 lda #5
 jsr readnbpfx ; read a entity addr
 bne nbpls.01 ; not available, do not proceed
 jsr whichnbp
 beq nbpls.04
 lda nbpbuffer+3 ; get actual socket
 ldy #nbppm.sktret
 sta (cmndlist),y
 dey
 cmp (cmndlist),y ; did it agree with what we ask for?
 do savespace
 beq nbpdone ; confirmed
 else
 bne *+5 ; different socket
 jmp nbpdone ; confirmed
 fin
 lda #diffsocket ; confirmed with wrong socket
 bne nbperror ; bra
nbpls.04 clc
 ldy #nbppm.rsbadr
 lda (cmndlist),y ; get response buffer and its boundary
 sta tblptr
 ldy #nbppm.rsbsiz
 adc (cmndlist),y
 sta nbpbflimit
 dey
 lda (cmndlist),y
 sta tblptr+1
 ldy #nbppm.rsbsiz+1
 adc (cmndlist),y
 sta nbpbflimit+1
 ldy #nbppm.rspnse ; get response received, this is current table size
 lda (cmndlist),y
 tax
 inx
 stx nbprcvct
nbpls.05 dec nbprcvct
 beq nbpls.10 ; not in table
 ldy #4 ; check if item is already in table
nbpls.06 lda (tblptr),y
 cmp nbpbuffer,y
 bne nbpls.07 ; not the same entry
 dey
 bpl nbpls.06
 jsr skipfield ; duplicate, ignore it
 bne nbprts ; ignore bad packet
 jsr skipfield
 bne nbprts ; ignore bad packet
 jsr skipfield
 bne nbprts ; ignore bad packet
nbpls.06c jmp nbpls.03
nbpls.07 ldy #5 ; points to entity name
 ldx #3 ; repeat for all three fields
nbpls.08 sec ; add 1 extra
 tya
 adc (tblptr),y ; add length count
 tay
 dex
 bne nbpls.08
 jsr inctblptr ; skip over entry in table
 beq nbpls.05 ; since inctblptr set z flag, bra -> check more from table
; we come to this point when nbprcvct is 0, indicate search is over
; we shall use the same location to indicate that whether buffer is full or not
; so we don't need to clear the flag and save 1 instruction
nbpls.10 lda #5
 sta rdmvvar
 jsr movenbp ; move entity addr
 jsr rdmvfield
 bcc rdmv.rts ; bad packet ignored
 jsr rdmvfield
 bcc rdmv.rts ; bad packet ignored
 jsr rdmvfield
 bcc rdmv.rts ; bad packet ignored
 lda #bufferfull ; assume buffer full
 ldy nbprcvct ; was buffer full ?
 bne nbperror ; then do not increase count
 ldy #nbppm.rspnse
 do savespace
 jsr incindy
 else
 clc
 lda (cmndlist),y ; increase item count
 adc #1
 sta (cmndlist),y
 fin
 dey ; y = 10
 cmp (cmndlist),y ; compare number of response
 bcc nbpls.06c ; still ok
nbpdone lda #0
nbperror ldy #0
 sty nbpptrsave+1 ; no more nbp operation
 jmp retasynsec ; set asyn result, do io completion, then sec carry
;
rdmvfield equ * ; read from field and move into table
 lda #1
 jsr readmove
 bne rdmv.rts ; operation failed
 lda nbpbuffer ; this is number of bytes
readmove sta rdmvvar
 jsr readnbp
 bne rdmv.rts
;jsr movenbp ; if read ok then move it
;rts
;
movenbp lda nbprcvct ; is table full already
 bne rdmvsec ; yes, do not move
 sec ; check if table can accept rdmvvar more bytes
 lda nbpbflimit
 sbc tblptr
 cmp rdmvvar
 bcs rdmv.1
 lda nbpbflimit+1
 sbc tblptr+1
 bcs rdmv.1 ; enough room
 sta nbprcvct ; since acc is non-zero, nbprcvct now indicate error
 rts ; returns with carry clear
rdmv.1 ldy rdmvvar ; enough room, then move it
 dey
rdmv.2 lda nbpbuffer,y ; and adjust table pointer
 sta (tblptr),y
 dey
 bpl rdmv.2
 lda rdmvvar
inctblptr clc
 adc tblptr
 sta tblptr
 bcc rdmv.7
 inc tblptr+1
rdmv.7 lda #0 ; set z flag
rdmvsec sec
rdmv.rts rts
;
skipfield lda #1
 jsr readnbpfx ; read field byte
 bne rdmv.rts
 lda nbpbuffer
; jsr readnbp ; read the field
; rts
; fall through to readnbp
;
readnbp cmp #33
 bcs rdnp.9 ; never read more than size of buffer
readnbpfx sta rnbpcnt ; number of bytes to read
 ifne opers-pascal
 ldy #<rnbpparm
 ldx #>rnbpparm
 else
 ldy adrrnbpparm+1
 ldx adrrnbpparm
 fin
 jmp readheader ; read the nbp header
rdnp.9 jmp discard
;
 ifeq opers-pascal
adrrnbpparm dw rnbpparm
 fin
 ifne opers-prodos
tuplect dfb 0
 fin
;
 ifeq opers-pascal
adrnbpwds dw nbpwds
 fin
;
rnbpparm dfb 5
 dw nbpbuffer
rnbpcnt dw 0
;
nbpwds ds 4,0 ; 4 bytes to be filled in
 dw 7,outnbp
entitylen dw 0
entityadr dw 0
 dw $ffff
